import { ref, watch } from 'vue';

// 传入获取值的函数和更新值的事件，返回 model
export function useModel<T>(
  getter: () => T,
  emitter: (val: T) => void,
  config?: {
    autoEmit?: boolean | undefined,
    autoWatch?: boolean | undefined,
    onChange?: (newVal: T, oldVal: T) => void,
  }
) {
  const state = ref(getter()) as { value: T};
  config = config || {}

  if (config.autoWatch !== false) {
    watch(getter, (val: T) => {
      if (val != state.value) {
        if (config!.onChange) {
          config!.onChange(val, state.value)
        }
        state.value = val
      }
    })
  }

  return {
    get value() {
      return state.value
    },
    set value(val: T) {
      state.value = val
      // 组件与用户交互的时候才能派发更新值的事件
      if (config!.autoEmit !== false) {
        emitter(val)
      }
    }
  };
}